import 'package:flutter/material.dart';

class CustomButton {
  static Map _buttonTypeConfig = {
    'warning': {
      'color': Color(0xFFFFF000),
      'bgColor': Color(0xFFFF976A),
      'borderColor': Color(0xFFFF976A),
    },
    'danger': {
      'color': Color(0xFFFFFFFF),
      'bgColor': Color(0xFFFF4444),
      'borderColor': Color(0xFFFF4444),
    },
    'info': {
      'color': Color(0xFFFFFFFF),
      'bgColor': Color(0xFF1989FA),
      'borderColor': Color(0xFF1989FA),
    },
    'primary': {
      'color': Color(0xFFFFFFFF),
      'bgColor': Color(0xFF07C160),
      'borderColor': Color(0xFF07C160),
    },
    'default': {
      'color': Color(0xFF323233),
      'bgColor': Color(0xFFFFFFFF),
      'borderColor': Color(0xFFEBEDF0),
    },
  };

  late Widget widget;

  static Color? _bgColor;
  static Color? _color;
  static Color _borderColor = Colors.transparent;

  final String? type;
  final Color? color;
  final Color? bgColor;
  final Color? borderColor;
  final double? width;
  final double? height;
  final bool plain;
  final VoidCallback? onPressed;
  final EdgeInsetsGeometry? padding;
  final BorderRadius? borderRadius;

  CustomButton.normal({
    this.width,
    this.height,
    this.type,
    this.color,
    this.bgColor,
    this.borderColor,
    required this.plain,
    this.onPressed,
    this.padding,
    this.borderRadius,
    required Widget child,
  }) {
    _setColor();
    widget = _init(child);
  }

  CustomButton.icon({
    this.width,
    this.height,
    this.type,
    this.color,
    this.bgColor,
    this.borderColor,
    required this.plain,
    this.onPressed,
    this.padding,
    this.borderRadius,
    Widget? textChild,
    required Widget icon,
  }) {
    _setColor();

    widget = _initIcon(textChild, icon);
  }

  CustomButton.loading({
    this.width,
    this.height,
    this.type,
    this.color,
    this.bgColor,
    this.borderColor,
    required this.plain,
    this.onPressed,
    this.padding,
    this.borderRadius,
    Widget? textChild,
    Widget? loadingChild,
  }) {
    _setColor();

    Widget defaultLoading = Transform.scale(
      scale: 0.7,
      child: CircularProgressIndicator(
        strokeWidth: 2,
        backgroundColor: Colors.transparent,
        valueColor: AlwaysStoppedAnimation(_color),
      ),
    );

    widget = _initIcon(textChild, defaultLoading);
  }

  _init(Widget child) {
    return SizedBox(
      width: width,
      height: height,
      child: MaterialButton(
        padding: padding ?? EdgeInsets.all(0),
        shape: RoundedRectangleBorder(
            borderRadius: borderRadius ?? BorderRadius.circular(4),
            side: BorderSide(
              width: 1,
              color: !plain ? Colors.transparent : _borderColor,
            )),
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        textColor: _color,
        color: _bgColor,
        splashColor: onPressed == null ? Colors.transparent : null,
        highlightColor: onPressed == null ? Colors.transparent : null,
        disabledColor: _bgColor,
        onPressed: onPressed ?? () {},
        child: child,
      ),
    );
  }

  _initIcon(Widget? textChild, Widget icon) {
    Widget iconChild = Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Container(
          child: icon,
        ),
        Container(
          margin: EdgeInsets.only(left: textChild == null ? 0 : 5),
          child: textChild,
        )
      ],
    );

    return _init(iconChild);
  }

  _getType() {
    var buttonColor = _buttonTypeConfig['$type'];
    buttonColor ??= _buttonTypeConfig['default'];
    return buttonColor;
  }

  _setColor() {
    Map buttonColor = _getType();

    Color $color = color ?? buttonColor['color'];
    Color $bgColor = bgColor ?? buttonColor['bgColor'];
    Color $borderColor = borderColor ?? buttonColor['borderColor'];

    if (plain) {
      if (color == null) {
        _color = onPressed == null ? $bgColor.withAlpha(127) : $bgColor;
      } else {
        _color = onPressed == null ? $color.withAlpha(127) : $color;
      }

      if (borderColor == null) {
        _borderColor = onPressed == null ? $bgColor.withAlpha(127) : $bgColor;
      } else {
        _borderColor =
            onPressed == null ? $borderColor.withAlpha(127) : $borderColor;
      }

      _bgColor = bgColor ?? Color(0xFFFFFFFF);
    } else {
      _color = onPressed == null ? $color.withAlpha(127) : $color;
      _bgColor = onPressed == null ? $bgColor.withAlpha(127) : $bgColor;
      _borderColor =
          onPressed == null ? $borderColor.withAlpha(127) : $borderColor;
    }
  }
}
